home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / src / acl.c.org < prev    next >
Encoding:
Text File  |  1999-04-06  |  29.1 KB  |  1,219 lines

  1. /* cfengine for GNU
  2.    
  3.    Copyright (C) 1995
  4.    Free Software Foundation, Inc.
  5.    
  6.    This file is part of GNU cfengine - written and maintained 
  7.    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
  8.    Dept. of Theoretical physics, University of Oslo
  9.    
  10.    This program is free software; you can redistribute it and/or modify it
  11.    under the terms of the GNU General Public License as published by the
  12.    Free Software Foundation; either version 2, or (at your option) any
  13.    later version.
  14.    
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.    
  20.    You should have received a copy of the GNU General Public License
  21.    along with this program; if not, write to the Free Software
  22.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  23. */
  24.  
  25. /**************************************************************************/
  26. /*                                                                        */
  27. /* File: acl.c                                                            */
  28. /* Author: Mark / Demosthenes / Patch by Goran Oberg                      */
  29. /*                                                                        */
  30. /**************************************************************************/
  31.  
  32. #include <stdio.h>
  33.  
  34. #include "cf.defs.h"
  35. #include "cf.extern.h"
  36.  
  37. #ifdef HAVE_SYS_ACL_H
  38. # include <sys/acl.h>
  39. #endif
  40.  
  41. #ifdef HAVE_DCE_DACLIF_H
  42. # include <dce/daclif.h>
  43. # include <dce/secidmap.h>
  44. # include <dce/binding.h>
  45. # include <dcedfs/aclint.h>
  46. # define SIZE_AVAIL (unsigned32) 2
  47. # define HAVE_DCE
  48.  
  49. # define MAX_TYPES          (unsigned32)2
  50. # define MAX_STRINGS        (unsigned32)16
  51. #endif
  52.  
  53. /*****************************************************************************/
  54.  
  55. char *CFFSTYPES[] =
  56. {
  57.     "posix",
  58.     "solaris",
  59.     "dfs",
  60.     "afs",
  61.     "hpux",
  62.     "nt",
  63.     NULL
  64. };
  65.  
  66. enum cffstype StringToFstype();
  67. struct CFACL *GetACL();
  68.  
  69. /*****************************************************************************/
  70.  
  71. #if defined SOLARIS && defined HAVE_SYS_ACL_H
  72. void
  73. aclsortperror(int error)
  74. {
  75.  switch (error)
  76.     {
  77.     case GRP_ERROR:
  78.     CfLog(cferror,"acl: There is more than one group_obj ACL entry.\n","");
  79.     break;
  80.     case USER_ERROR:
  81.     CfLog(cferror,"acl: There is more than one user_obj ACL entry.\n","");
  82.     break;
  83.     case CLASS_ERROR:
  84.     CfLog(cferror,"acl: There is more than one class_obj ACL entry.\n", "");
  85.     break;
  86.     case OTHER_ERROR:
  87.     CfLog(cferror,"acl: There is more than one other_obj ACL entry.\n", "");
  88.     break;
  89.     case DUPLICATE_ERROR:
  90.     CfLog(cferror,"acl: Duplicate entries of user or group.\n", "");
  91.     break;
  92.     case ENTRY_ERROR:
  93.     CfLog(cferror,"acl: The entry type is invalid.\n", "");
  94.     break;
  95.     case MISS_ERROR:
  96.     CfLog(cferror,"acl: Missing group_obj, user_obj, class_obj, or other_obj entries.\n", "");
  97.     break;
  98.     case MEM_ERROR:
  99.     CfLog(cferror,"acl: The system can't allocate any memory.\n", "");
  100.     break;
  101.     default:
  102.     sprintf(OUTPUT,"acl: Unknown ACL error code: %d !\n", error);
  103.     CfLog(cferror,OUTPUT,"");
  104.     break;
  105.     }
  106.  return;
  107. }
  108. #endif
  109.  
  110. /*****************************************************************************/
  111.  
  112. #ifdef HAVE_DCE
  113. sec_acl_entry_type_t
  114. BuildDceAclEntry_Type(char *t, char *n)
  115. {
  116.  if (strcmp(t, "user") == 0)
  117.     {
  118.     if (*n == 0)
  119.        {
  120.        return sec_acl_e_type_user_obj;
  121.        }
  122.     else
  123.        {
  124.        return sec_acl_e_type_user;
  125.        }
  126.     }
  127.  else if (strcmp(t, "group") == 0)
  128.     {
  129.     if (*n == 0)
  130.        {
  131.        return sec_acl_e_type_group_obj;
  132.        }
  133.     else
  134.        {
  135.        return sec_acl_e_type_group;
  136.        }
  137.     }
  138.  else if (strcmp(t, "other") == 0)
  139.     {
  140.     return sec_acl_e_type_other_obj;
  141.     }
  142.  else if (strcmp(t, "mask") == 0)
  143.     {
  144.     return sec_acl_e_type_mask_obj;
  145.     }
  146.  else if (strcmp(t, "any") == 0)
  147.     {
  148.     return sec_acl_e_type_any_other;
  149.     }
  150.  else if (strcmp(t, "unauthenticated") == 0)
  151.     {
  152.     return sec_acl_e_type_unauthenticated;
  153.     }
  154.  else if (strcmp(t, "foreign_other") == 0)
  155.     {
  156.     return sec_acl_e_type_foreign_other;
  157.     }
  158.  else if (strcmp(t, "foreign_user") == 0)
  159.     {
  160.     return sec_acl_e_type_foreign_user;
  161.     }
  162.  else if (strcmp(t, "foreign_group") == 0)
  163.     {
  164.     return sec_acl_e_type_foreign_group;
  165.     }
  166.  return 0;
  167. }
  168.  
  169. /*****************************************************************************/
  170.  
  171. sec_acl_permset_t
  172. BuildDceAclEntry_Perms(char *mode, sec_acl_permset_t oldmode)
  173. {
  174.  sec_acl_permset_t perm = 0;
  175.  char *a;
  176.  enum {add, del} o;
  177.  perm = oldmode;
  178.  
  179.  if (strcmp(mode, "noaccess") == 0)
  180.     {
  181.     return 0; /* No access for this user/group */
  182.     }
  183.  
  184.  o = add;
  185.  for (a = mode; *a != '\0' ; *a++)
  186.     {
  187.     if (*a == '+' || *a == ',')
  188.        {
  189.        o = add;
  190.        }
  191.     else if (*a == '-')
  192.        {
  193.        o = del;
  194.        }
  195.     else if (*a == '=')
  196.        {
  197.        o = add;
  198.        perm = 0;
  199.        }
  200.     else
  201.        {
  202.        switch (*a)
  203.       {
  204.       case 'r':
  205.           if (o == add)
  206.          {
  207.          perm |= sec_acl_perm_read;
  208.          }
  209.           else
  210.          {
  211.          perm &= ~sec_acl_perm_read;
  212.          }
  213.           break;
  214.       case 'w': 
  215.           if (o == add)
  216.          {
  217.          perm |= sec_acl_perm_write;
  218.          }
  219.           else
  220.          {
  221.          perm &= ~sec_acl_perm_write;
  222.          }
  223.           break;
  224.       case 'x': 
  225.           if (o == add)
  226.          {
  227.          perm |= sec_acl_perm_execute;
  228.          }
  229.           else
  230.          {
  231.          perm &= ~sec_acl_perm_execute;
  232.          }
  233.           break;
  234.       case 'c': 
  235.           if (o == add)
  236.          {
  237.          perm |= sec_acl_perm_control;
  238.          }
  239.           else
  240.          {
  241.          perm &= ~sec_acl_perm_control;
  242.          }
  243.           break;
  244.       case 'i': 
  245.           if (o == add)
  246.          {
  247.          perm |= sec_acl_perm_insert;
  248.          }
  249.           else
  250.          {
  251.          perm &= ~sec_acl_perm_insert;
  252.          }
  253.           break;
  254.       case 'd': 
  255.           if (o == add)
  256.          {
  257.          perm |= sec_acl_perm_delete;
  258.          }
  259.           else
  260.          {
  261.          perm &= ~sec_acl_perm_delete;
  262.          }
  263.           break;
  264.       default:  
  265.           sprintf(OUTPUT,"Invalid mode string in DCE/DFS acl: %s\n", mode);
  266.           CfLog(cferror,OUTPUT,"");
  267.       }
  268.        }
  269.     }
  270.  return perm;
  271. }
  272.  
  273. /*****************************************************************************/
  274.  
  275. uuid_t
  276. BuildDceAclEntry_Id(sec_rgy_handle_t rgy_site, sec_rgy_name_t name, sec_acl_entry_type_t type)
  277. {
  278.  uuid_t id;
  279.  error_status_t status;
  280.  
  281.  bzero(id, sizeof(id));
  282.  switch (type)
  283.     {
  284.     case sec_acl_e_type_group:
  285.     sec_id_parse_group(rgy_site, name, NULL, NULL, NULL, &id, &status);
  286.     if (status != error_status_ok)
  287.        {
  288.        sprintf(OUTPUT,"sec_rgy_parse_group: %ld\n", status);
  289.        CfLog(cferror,OUTPUT,"");
  290.        }
  291.     break;
  292.     case sec_acl_e_type_user:
  293.     sec_id_parse_name(rgy_site, name, NULL, NULL, NULL, &id, &status);
  294.     if (status != error_status_ok)
  295.        {
  296.        sprintf(OUTPUT,"sec_rgy_parse_name: %ld\n", status);
  297.        CfLog(cferror,OUTPUT,"");
  298.        }
  299.     break;
  300.     case sec_acl_e_type_foreign_group:
  301.     CfLog(cferror,"acl type c_acl_e_type_foreign_group not supported yet\n","");
  302.     break;
  303.     case sec_acl_e_type_foreign_user:
  304.     CfLog(cferror,"acl type sec_acl_e_type_foreign_user not supported yet.\n","");
  305.     break;
  306.     case sec_acl_e_type_foreign_other:
  307.     CfLog(cferror,"acl type sec_acl_e_type_foreign_other not supported yet.\n","");
  308.     break;
  309.     default:
  310.     CfLog(cferror,"Unknown acl type in BuildDceAclEntry_Id!\n","");
  311.     break;
  312.     }
  313.  return id;
  314. }
  315. #endif
  316.  
  317. /*****************************************************************************/
  318.  
  319. #if defined SOLARIS && defined HAVE_SYS_ACL_H
  320.  
  321. int
  322. ParseSolarisMode(char* mode, mode_t oldmode)
  323. {
  324.  char *a;
  325.  mode_t perm;
  326.  enum {add, del} o;
  327.  
  328.  perm = oldmode;
  329.  if (strcmp(mode, "noaccess") == 0)
  330.     {
  331.     return 0; /* No access for this user/group */
  332.     }
  333.  
  334.  o = add;
  335.  for (a = mode; *a != '\0' ; *a++)
  336.     {
  337.     if (*a == '+' || *a == ',')
  338.        {
  339.        o = add;
  340.        }
  341.     else if (*a == '-')
  342.        {
  343.        o = del;
  344.        }
  345.     else if (*a == '=')
  346.        {
  347.        o = add;
  348.        perm = 0;
  349.        }
  350.     else
  351.        {
  352.        switch (*a)
  353.       {
  354.       case 'r':
  355.           if (o == add)
  356.          {
  357.          perm |= 04;
  358.          }
  359.           else
  360.          {
  361.          perm &= ~04;
  362.          }
  363.           break;
  364.       case 'w': 
  365.           if (o == add)
  366.          {
  367.          perm |= 02;
  368.          }
  369.           else
  370.          {
  371.          perm &= ~02;
  372.          }
  373.           break;
  374.       case 'x': 
  375.           if (o == add)
  376.          {
  377.          perm |= 01;
  378.          }
  379.           else
  380.          {
  381.          perm &= ~01;
  382.          }
  383.           break;
  384.       default:  
  385.           sprintf(OUTPUT,"Invalid mode string in solaris acl: %s\n", mode);
  386.           CfLog(cferror,OUTPUT,"");
  387.       }
  388.        }
  389.     }
  390.  
  391.  return perm;
  392. }
  393.  
  394. int
  395. BuildAclEntry(struct stat *sb, char *acltype, char *name, struct acl *newaclbufp)
  396. {
  397.  struct passwd *pw;
  398.  struct group *gr;
  399.  
  400.  if (strcmp(acltype, "user") == 0)
  401.     {
  402.     if (*name == 0)
  403.        {
  404.        newaclbufp->a_type = USER_OBJ;
  405.        newaclbufp->a_id = sb->st_uid;
  406.        }
  407.     else 
  408.        {
  409.        newaclbufp->a_type = USER;
  410.        if ((pw = getpwnam(name)) != NULL)
  411.       {
  412.       newaclbufp->a_id = pw->pw_uid;
  413.       }
  414.        else
  415.       {
  416.       sprintf(OUTPUT,"acl: no such user: %s\n",name);
  417.       CfLog(cferror,OUTPUT,"");
  418.       return -1;
  419.       }
  420.        }
  421.     }
  422.  else if (strcmp(acltype, "group") == 0)
  423.     {
  424.     if (*name == 0)
  425.        {
  426.        newaclbufp->a_type = GROUP_OBJ;
  427.        newaclbufp->a_id = sb->st_gid;
  428.        }
  429.     else
  430.        {
  431.        newaclbufp->a_type = GROUP;
  432.        if ((gr = getgrnam(name)) != NULL)
  433.       {
  434.       newaclbufp->a_id = gr->gr_gid;
  435.       }
  436.        else
  437.       {
  438.       sprintf(OUTPUT,"acl: no such group: %s\n",name);
  439.       CfLog(cferror,OUTPUT,"");
  440.       return -1;
  441.       }
  442.        }
  443.     }
  444.  else if (strcmp(acltype, "mask") == 0)
  445.     {
  446.     newaclbufp->a_type = CLASS_OBJ;
  447.     newaclbufp->a_id = 0;
  448.     }
  449.  else if (strcmp(acltype, "other") == 0)
  450.     {
  451.     newaclbufp->a_type = OTHER_OBJ;
  452.     newaclbufp->a_id = 0;
  453.     }
  454.  else if (strcmp(acltype, "default_user") == 0)
  455.     {
  456.     if (*name == 0)
  457.        {
  458.        newaclbufp->a_type = DEF_USER_OBJ;
  459.        newaclbufp->a_id = 0;
  460.        }
  461.     else
  462.        {
  463.        newaclbufp->a_type = DEF_USER;
  464.        if ((pw = getpwnam(name)) != NULL)
  465.       {
  466.       newaclbufp->a_id = pw->pw_uid;
  467.       }
  468.        else
  469.       {
  470.       sprintf(OUTPUT,"%s: acl: no such user: %s\n", VPREFIX, name);
  471.       CfLog(cferror,OUTPUT,"");
  472.       return -1;
  473.       }
  474.        }
  475.     }
  476.  else if (strcmp(acltype, "default_group") == 0)
  477.     {
  478.     if (*name == 0)
  479.        {
  480.        newaclbufp->a_type = DEF_GROUP_OBJ;
  481.        newaclbufp->a_id = 0;
  482.        }
  483.     else
  484.        {
  485.        newaclbufp->a_type = DEF_GROUP;
  486.        if ((gr = getgrnam(name)) != NULL)
  487.       {
  488.       newaclbufp->a_id = gr->gr_gid;
  489.       }
  490.        else
  491.       {
  492.       sprintf(OUTPUT,"acl: no such group: %s\n",name);
  493.       CfLog(cferror,OUTPUT,"");
  494.       return -1;
  495.       }
  496.        }
  497.     }
  498.  else if (strcmp(acltype, "default_mask") == 0)
  499.     {
  500.     newaclbufp->a_type = DEF_CLASS_OBJ;
  501.     newaclbufp->a_id = 0;
  502.     }
  503.  else if (strcmp(acltype, "default_other") == 0)
  504.     {
  505.     newaclbufp->a_type = DEF_OTHER_OBJ;
  506.     newaclbufp->a_id = 0;
  507.     }
  508.  
  509.  newaclbufp->a_perm = 0;
  510.  
  511.  return 0;
  512. }
  513. #endif
  514.  
  515. /*****************************************************************************/
  516.  
  517. InstallACL(alias,classes)
  518.  
  519. char *alias, *classes;
  520.  
  521. { struct CFACL *ptr;
  522.  
  523.  Debug1("InstallACL(%s,%s)\n",alias,classes);
  524.  
  525.  if (! IsInstallable(classes))
  526.     {
  527.     Debug1("Not installing ACL no match\n");
  528.     return;
  529.     }
  530.  
  531.  VBUFF[0]='\0';                         /* Expand any variables */
  532.  ExpandVarstring(alias,VBUFF,"");
  533.  
  534.  if ((ptr = (struct CFACL *)malloc(sizeof(struct CFACL))) == NULL)
  535.     {
  536.     FatalError("Memory Allocation failed for InstallACL() #1");
  537.     }
  538.  
  539.  if ((ptr->acl_alias = strdup(VBUFF)) == NULL)
  540.     {
  541.     FatalError("Memory Allocation failed for InstallEditFile() #2");
  542.     }
  543.  
  544.  if (VACLLISTTOP == NULL)                 /* First element in the list */
  545.     {
  546.     VACLLIST = ptr;
  547.     }
  548.  else
  549.     {
  550.     VACLLISTTOP->next = ptr;
  551.     }
  552.  
  553.  ptr->aces = NULL;
  554.  ptr->next = NULL;
  555.  ptr->method = 'o';
  556.  ptr->type = StringToFstype("none"); 
  557.  VACLLISTTOP = ptr;
  558. }
  559.  
  560. /*****************************************************************************/
  561.  
  562. AddACE(acl,string,classes)
  563.  
  564. char *acl, *string, *classes;
  565.  
  566. { struct CFACL *ptr;
  567.  struct CFACE *new, *top;
  568.  char varbuff[bufsize], *cp;
  569.  char comm[maxvarsize],data1[maxvarsize],data2[maxvarsize];
  570.  int i;
  571.  
  572.  Debug1("AddACE(%s,%s,[%s])\n",acl,string,classes);
  573.  
  574.  if ( ! IsInstallable(CLASSBUFF))
  575.     {
  576.     Debug1("Not installing ACE no match\n");
  577.     return;
  578.     }
  579.  
  580.  for (ptr = VACLLIST; ptr != NULL; ptr=ptr->next)
  581.     {
  582.     varbuff[0] = '\0';
  583.     ExpandVarstring(acl,varbuff,"");
  584.     
  585.     if (strcmp(ptr->acl_alias,varbuff) == 0)
  586.        {
  587.        comm[0] = data1[0] = data2[0] = '\0';
  588.        
  589.        if ((new = (struct CFACE *)calloc(1,sizeof(struct CFACE))) == NULL)
  590.       {
  591.       FatalError("Memory Allocation failed for AddEditAction() #1");
  592.       }
  593.        
  594.        if (ptr->aces == NULL)
  595.       {
  596.       ptr->aces = new;
  597.       }
  598.        else
  599.       {
  600.       for (top = ptr->aces; top->next != NULL; top=top->next)
  601.          {
  602.          }
  603.       top->next = new;
  604.       new->next = NULL;
  605.       }
  606.        
  607.        if (string == NULL)
  608.       {
  609.       new->name = NULL;
  610.       new->next = NULL;
  611.       }
  612.        else
  613.       {
  614.       bzero(VBUFF, sizeof(VBUFF));
  615.       VBUFF[0]='\0';                         /* Expand any variables */
  616.       ExpandVarstring(string,VBUFF,"");
  617.       
  618.       cp = VBUFF;
  619.       i = 0;
  620.       while (*cp != ':' && *cp != '\0') {
  621.       comm[i++] = *cp++;
  622.       }
  623.       comm[i] = 0;
  624.       *cp++;
  625.       
  626.       i = 0;
  627.       while (*cp != ':' && *cp != '\0') {
  628.       data1[i++] = *cp++;
  629.       }
  630.       data1[i] = 0;
  631.       *cp++;
  632.       
  633.       i = 0;
  634.       while (*cp != ':' && *cp != '\0') {
  635.       data2[i++] = *cp++;
  636.       }
  637.       data2[i] = 0;
  638.       
  639.       if (strncmp("fstype",comm,strlen(comm)) == 0)
  640.          {
  641.          ptr->type = StringToFstype(data1);
  642.          new->next = NULL;
  643.          return;
  644.          }
  645.       
  646.       if (strncmp("method",comm,strlen(comm)) == 0)
  647.          {
  648.          ptr->method = ToLower(*data1);
  649.          new->next = NULL;
  650.          return;
  651.          }
  652.       
  653.       if ((new->acltype = strdup(comm)) == NULL)
  654.          {
  655.          FatalError("Memory Allocation failed for AddACE() #1");
  656.          }
  657.       
  658.       if ((new->name = strdup(data1)) == NULL)
  659.          {
  660.          FatalError("Memory Allocation failed for AddACE() #2");
  661.          }
  662.       
  663.       if ((new->mode = strdup(data2)) == NULL)
  664.          {
  665.          FatalError("Memory Allocation failed for AddACE() #2");
  666.          }
  667.       }
  668.        
  669.        if ((new->classes = strdup(classes)) == NULL)
  670.       {
  671.       FatalError("Memory Allocation failed for InstallEditFile() #3");
  672.       }
  673.        return;
  674.        }
  675.     }
  676.  
  677.  printf("cfengine: software error - no ACL matched installing %s \n",acl);
  678. }
  679.  
  680. /*****************************************************************************/
  681.  
  682. CheckACLs(filename,action,acl_aliases)
  683.  
  684. char *filename;
  685. enum fileactions action;
  686. struct Item *acl_aliases;
  687.  
  688. { struct Item *ip;
  689.  struct CFACL *ap;
  690.  int status = false;
  691.  
  692.  Debug1("CheckACLs(%s)\n",filename);
  693.  
  694.  for (ip = acl_aliases; ip != NULL; ip = ip->next)
  695.     {
  696.     if ((ap = GetACL(ip->name)) != NULL)
  697.        {
  698.        Verbose(" ACL method (overwrite/append) = %c on %s\n",ap->method,filename);
  699.        
  700.        switch(ap->type)
  701.       {
  702.       case solarisfs:
  703.       case posixfs:
  704.           status = CheckPosixACE(ap->aces,ap->method,filename,action);
  705.           break;
  706.       case dfsfs:
  707.           status = CheckDFSACE(ap->aces,ap->method,filename,action);
  708.           break;
  709.       default:
  710.           sprintf("Unknown filesystem type in ACL %s\n",ip->name);
  711.           CfLog(cferror,OUTPUT,"");
  712.       }
  713.        }
  714.     else
  715.        {
  716.        Verbose("ACL %s does not exist (file=%s)\n",ip->name,filename);
  717.        }
  718.     }
  719.  return status;
  720. }
  721.  
  722.  
  723. /*****************************************************************************/
  724. /* Level 2                                                                   */
  725. /*****************************************************************************/
  726.  
  727. enum cffstype StringToFstype(string)
  728.  
  729. char *string;
  730.  
  731. { int i;
  732.  
  733.  for (i = 0; CFFSTYPES[i] != NULL; i++)
  734.     {
  735.     if (strcmp(string,CFFSTYPES[i]) == 0)
  736.        {
  737.        return (enum cffstype) i;
  738.        }
  739.     }
  740.  
  741.  return (enum cffstype) i;
  742. }
  743.  
  744. /*****************************************************************************/
  745.  
  746. struct CFACL *GetACL(acl_alias)
  747.  
  748. char *acl_alias;
  749.  
  750. { struct CFACL *ap;
  751.  
  752.  for (ap = VACLLIST; ap != NULL; ap = ap->next)
  753.     {
  754.     if (strcmp(acl_alias,ap->acl_alias) == 0)
  755.        {
  756.        return ap;
  757.        }
  758.     }
  759.  
  760.  return NULL; 
  761. }
  762.  
  763. /*****************************************************************************/
  764.  
  765. CheckPosixACE(aces,method,filename,action)
  766. struct CFACE *aces;
  767. char method;
  768. char *filename;
  769. enum fileactions action;
  770. {
  771. #if defined(HAVE_SYS_ACL_H) && defined(SOLARIS)
  772.  struct CFACE *ep;
  773.  aclent_t aclbufp[MAX_ACL_ENTRIES], newaclbufp[MAX_ACL_ENTRIES], tmpacl;
  774.  int nacl = 0, newacls = 0, status = 0, update = 0, i, j;
  775.  struct stat sb;
  776.  uid_t myuid;
  777.  
  778.  bzero(aclbufp, sizeof(aclbufp));
  779.  bzero(newaclbufp, sizeof(newaclbufp));
  780.  nacl = acl (filename, GETACLCNT, 0, NULL);
  781.  nacl = acl (filename, GETACL, nacl, aclbufp);
  782.  
  783.  if (stat(filename, &sb) != 0)
  784.     {
  785.     CfLog(cferror,"","stat");
  786.     return -1;
  787.     }
  788.  
  789.  Verbose(" Old acl has %d entries and is:\n", nacl);
  790.  
  791.  for (i = 0; i < nacl; i++)
  792.     {
  793.     Debug1(" a_type = %x, \ta_id = %d, \ta_perm = %o\n",
  794.        aclbufp[i].a_type, aclbufp[i].a_id, aclbufp[i].a_perm);
  795.     }
  796.  
  797.  Debug1("method = %c\n", method);
  798.  
  799.  if (method == 'a')
  800.     {
  801.     newacls = nacl;
  802.     for (i = 0; i < nacl; i++)
  803.        {
  804.        newaclbufp[i].a_id = aclbufp[i].a_id;
  805.        newaclbufp[i].a_type = aclbufp[i].a_type;
  806.        newaclbufp[i].a_perm = aclbufp[i].a_perm;
  807.        }
  808.     }   
  809.  
  810.  for (ep = aces; ep !=NULL; ep = ep->next)
  811.     {
  812.     if (ep->name == NULL)
  813.        {
  814.        continue;
  815.        }
  816.     if(IsExcluded(ep->classes))
  817.        {
  818.        continue;
  819.        }
  820.     
  821.     Verbose("%s: Mode =%s, name=%s, type=%s\n",VPREFIX,ep->mode,ep->name,ep->acltype);
  822.     if (strcmp(ep->name, "*") == 0)
  823.        {
  824.        bzero (ep->name, sizeof(ep->name));
  825.        }
  826.     
  827.     if (BuildAclEntry(&sb,ep->acltype,ep->name,&tmpacl) == 0)
  828.        {
  829.        status = 0;
  830.        for (i = 0; i < newacls; i++)
  831.       {
  832.       if (newaclbufp[i].a_id == tmpacl.a_id && newaclbufp[i].a_type == tmpacl.a_type)
  833.          {
  834.          status = 1;
  835.          if (strcmp(ep->mode, "default") == 0)
  836.         {
  837.         sprintf(OUTPUT,"Deleting ACL entry %d: type = %x,\tid = %d,\tperm = %o\n",
  838.             i, newaclbufp[i].a_type, newaclbufp[i].a_id, newaclbufp[i].a_perm);
  839.         CfLog(cfverbose,OUTPUT,"");
  840.         newacls--;
  841.         newaclbufp[i].a_id = newaclbufp[newacls].a_id;
  842.         newaclbufp[i].a_type = newaclbufp[newacls].a_type;
  843.         newaclbufp[i].a_perm = newaclbufp[newacls].a_perm;
  844.         }
  845.          else
  846.         {
  847.         tmpacl.a_perm = ParseSolarisMode(ep->mode, newaclbufp[i].a_perm);
  848.         if (tmpacl.a_perm != newaclbufp[i].a_perm)
  849.            {
  850.            newaclbufp[i].a_id = tmpacl.a_id;
  851.            newaclbufp[i].a_type = tmpacl.a_type;
  852.            newaclbufp[i].a_perm = tmpacl.a_perm;
  853.            
  854.            sprintf(OUTPUT,"Replaced ACL entry %d: type = %x,\tid = %d,\tperm = %o\n",
  855.                i, newaclbufp[i].a_type, newaclbufp[i].a_id, newaclbufp[i].a_perm);
  856.            CfLog(cfverbose,OUTPUT,"");
  857.            }
  858.         }
  859.          }
  860.       }
  861.        }
  862.     if (status == 0 && (strcmp(ep->mode, "default") != 0))
  863.        {
  864.        newaclbufp[newacls].a_id = tmpacl.a_id;
  865.        newaclbufp[newacls].a_type = tmpacl.a_type;
  866.        newaclbufp[newacls].a_perm = ParseSolarisMode(ep->mode, 0);
  867.        newacls++;
  868.        
  869.        sprintf(OUTPUT,"Added ACL entry %d: type = %x,\tid = %d,\tperm = %o\n",
  870.            i, newaclbufp[i].a_type, newaclbufp[i].a_id, newaclbufp[i].a_perm);
  871.        CfLog(cfverbose,OUTPUT,"");
  872.        }
  873.     }
  874.  
  875.  if (newacls != nacl)
  876.     {
  877.     update = 1;
  878.     }
  879.  else
  880.     {
  881.     for (i = 0 ; i < nacl ; i++)
  882.        {
  883.        status = 0;
  884.        for (j = 0 ; j < newacls ; j++)
  885.       {
  886.       if (aclbufp[i].a_id == newaclbufp[j].a_id && aclbufp[i].a_type == newaclbufp[j].a_type && aclbufp[i].a_perm == newaclbufp[j].a_perm)
  887.          {
  888.          status = 1;
  889.          }
  890.       }
  891.        if (status == 0)
  892.        update = 1;
  893.        }
  894.     }
  895.  
  896.  if (update == 0)
  897.     {
  898.     Verbose("no update necessary\n");
  899.     return false;
  900.     }
  901.  
  902.  if (action == warnall || action == warnplain || action == warndirs)
  903.     {
  904.     sprintf(OUTPUT,"File %s needs ACL update\n",filename);
  905.     CfLog(cfinform,OUTPUT,"");
  906.     return false;
  907.     }
  908.  
  909.  if ((status = aclcheck(newaclbufp, newacls, &i)) != 0)
  910.     {
  911.     printf("aclcheck failed\n");
  912.     aclsortperror(status);
  913.     return false;
  914.     }
  915.  
  916.  if (aclsort(newacls, 0, (aclent_t *) newaclbufp) != 0)
  917.     {
  918.     printf("%s: aclsort failed\n", VPREFIX);
  919.     return false;
  920.     }
  921.  
  922.  Debug1("new acl has %d entries and is:\n", newacls);
  923.  for (i = 0; i < newacls; i++)
  924.     {
  925.     Debug1 ("a_type = %x,\ta_id = %d,\ta_perm = %o\n",
  926.         newaclbufp[i].a_type, newaclbufp[i].a_id, newaclbufp[i].a_perm);
  927.     }
  928.  
  929.  Debug1("setting acl of %s with %d acl-entries\n", filename, newacls);
  930.  
  931.  myuid = getuid();
  932.  if (sb.st_uid != myuid)
  933.     {
  934.     if (myuid == 0)
  935.        {
  936.        Verbose("Changing effective uid to %ld\n", (long)sb.st_uid);
  937.        if (seteuid(sb.st_uid) == -1)
  938.           {
  939.       sprintf(OUTPUT,"Couldn't set effective uid from %ld to %ld\n",(long)myuid,(long)sb.st_uid);
  940.       CfLog(cferror,OUTPUT,"seteuid");
  941.       return false;
  942.           }
  943.        Debug1("effective uid now %ld\n", (long)sb.st_uid);
  944.        }
  945.     else
  946.        {
  947.        sprintf(OUTPUT,"Can't set effective uid from %ld to %ld, not super-user!\n",
  948.            (long)myuid, (long)sb.st_uid);
  949.        CfLog(cferror,OUTPUT,"seteuid");
  950.        return false;
  951.        }
  952.     
  953.     Debug1("now the correct uid to manage acl of %s\n", filename, newacls);
  954.     
  955.     
  956.     if (acl (filename, SETACL, newacls, newaclbufp) != newacls)
  957.        {
  958.        CfLog(cferror,"","acl");
  959.        return false;
  960.        }
  961.     
  962.     Debug1("setting acl of %s resulted in %d acl-entries\n",
  963.            filename, newacls);
  964.     
  965.     if (seteuid(myuid) == -1)
  966.        {
  967.        sprintf(OUTPUT,"Unable to regain privileges of user %ld\n",
  968.            (long)myuid);
  969.        CfLog(cferror,OUTPUT,"seteuid");
  970.        FatalError("Aborting cfengine");
  971.        }
  972.     }
  973.  else
  974.     {
  975.     if (acl(filename, SETACL, newacls, newaclbufp) != newacls)
  976.        {
  977.        CfLog(cferror,"","acl");
  978.        return false;
  979.        }
  980.     Debug1("setting acl of %s resulted in %d acl-entries\n", filename, newacls);
  981.     }
  982.  
  983.  sprintf(OUTPUT,"ACL for file %s updated\n",filename);
  984.  CfLog(cfinform,OUTPUT,"");
  985.  
  986.  return true;
  987. #else
  988.  Verbose("Can't do ACLs on this system...\n");
  989. #endif
  990. }
  991.  
  992. /*****************************************************************************/
  993.  
  994.  
  995. CheckDFSACE(aces,method,filename,action)
  996. struct CFACE *aces;
  997. char method;
  998. char *filename;
  999. enum fileactions action;
  1000. {
  1001. #ifdef HAVE_DCE
  1002.  
  1003.  struct CFACE *ep;
  1004.  sec_acl_handle_t h;
  1005.  sec_acl_list_t acl_list;
  1006.  error_status_t status;
  1007.  unsigned32 size_used, num_types;
  1008.  uuid_t manager_types[SIZE_AVAIL];
  1009.  sec_rgy_handle_t rgy_site;
  1010.  uuid_t cell_uuid;
  1011.  sec_rgy_properties_t properties;
  1012.  sec_acl_p_t new_sec_acls[1];
  1013.  int update = 0;
  1014.  int index = 0;
  1015.  int i, j;
  1016.  sec_acl_entry_type_t type;
  1017.  sec_acl_permset_t perms, ptmp;
  1018.  uuid_t id;
  1019.  
  1020.  sec_rgy_site_open ("/.:", &rgy_site, &status);
  1021.  
  1022.  if (status != error_status_ok)
  1023.     {
  1024.     sprintf(OUTPUT,"DCE: sec_rgy_site_open: %ld\n", status);
  1025.     CfLog(cferror,OUTPUT,"");
  1026.     }
  1027.  
  1028.  sec_id_parse_name (rgy_site, "", NULL, &cell_uuid, NULL, NULL, &status);
  1029.  
  1030.  if (status != error_status_ok)
  1031.     {
  1032.     sprintf(OUTPUT,"DCE: sec_rgy_parse_name: %ld\n", status);
  1033.     CfLog(cferror,OUTPUT,"");
  1034.     }
  1035.  
  1036.  sec_rgy_properties_get_info(rgy_site, &properties, &status);
  1037.  if (status != error_status_ok)
  1038.     {
  1039.     sprintf(OUTPUT,"DCE: sec_rgy_properties_get_info: %ld\n", status);
  1040.     CfLog(cferror,OUTPUT,"");
  1041.     }
  1042.  
  1043.  sec_acl_bind (filename, FALSE, &h, &status);
  1044.  
  1045.  if (status != error_status_ok)
  1046.     {
  1047.     sprintf(OUTPUT,"DCE: sec_acl_bind: %ld\n", status);
  1048.     CfLog(cferror,OUTPUT,"");
  1049.     }
  1050.  
  1051.  sec_acl_get_manager_types (h, sec_acl_type_object, SIZE_AVAIL,
  1052.                             &size_used, &num_types, manager_types, &status);
  1053.  
  1054.  if (status != error_status_ok)
  1055.     {
  1056.     sprintf(OUTPUT,"DCE: sec_acl_get_manager_types: %ld\n", status);
  1057.     CfLog(cferror,OUTPUT,"");
  1058.     }
  1059.  
  1060.  if (num_types == 0)
  1061.     {
  1062.     sprintf(OUTPUT,"DCE: No ACL manager!\n");
  1063.     CfLog(cferror,OUTPUT,"");
  1064.     }
  1065.  
  1066.  if (size_used < num_types)
  1067.     {
  1068.     sprintf(OUTPUT,"Warning: some manager types missed\n");
  1069.     CfLog(cfsilent,OUTPUT,"");
  1070.     }
  1071.  
  1072.  sec_acl_lookup (h, manager_types, sec_acl_type_object, &acl_list, &status);
  1073.  
  1074.  if (status != error_status_ok)
  1075.     {
  1076.     sprintf (OUTPUT,"DCE: sec_acl_lookup: %ld\n", status);
  1077.     CfLog(cferror,OUTPUT,"");
  1078.     }
  1079.  
  1080.  Debug1("method = %c\n", method);
  1081.  
  1082.  /* new_sec_acls[0]= calloc(1, sizeof(sec_acl_p_t));*/
  1083.  new_sec_acls[0]= calloc(1, sizeof(sec_acl_t));
  1084.  
  1085.  new_sec_acls[0]->sec_acl_entries = calloc(MAXDFSACL, sizeof(sec_acl_entry_t));
  1086.  new_sec_acls[0]->default_realm = acl_list.sec_acls[0]->default_realm;
  1087.  new_sec_acls[0]->sec_acl_manager_type = acl_list.sec_acls[0]->sec_acl_manager_type;
  1088.  new_sec_acls[0]->num_entries = 0;
  1089.  
  1090.  if (method == 'a')
  1091.     {
  1092.     new_sec_acls[0]->num_entries = acl_list.sec_acls[0]->num_entries;
  1093.     for (i = 0; i < acl_list.sec_acls[0]->num_entries; i++)
  1094.        {
  1095.        new_sec_acls[0]->sec_acl_entries[i].entry_info.entry_type = acl_list.sec_acls[0]->sec_acl_entries[i].entry_info.entry_type;
  1096.        new_sec_acls[0]->sec_acl_entries[i].perms = acl_list.sec_acls[0]->sec_acl_entries[i].perms;
  1097.        new_sec_acls[0]->sec_acl_entries[i].entry_info.tagged_union = acl_list.sec_acls[0]->sec_acl_entries[i].entry_info.tagged_union;
  1098.        }
  1099.     }
  1100.  
  1101.  for (ep = aces; ep !=NULL; ep = ep->next)
  1102.     {
  1103.     if (ep->name == NULL)
  1104.        {
  1105.        continue;
  1106.        }
  1107.     
  1108.     if(IsExcluded(ep->classes))
  1109.        {
  1110.        continue;
  1111.        }
  1112.     
  1113.     Verbose("%s: Mode =%s, name=%s, type=%s\n",VPREFIX,ep->mode,ep->name,ep->acltype);
  1114.     if (strcmp(ep->name, "*") == 0)
  1115.        {
  1116.        bzero (ep->name, sizeof(ep->name));
  1117.        }
  1118.     
  1119.     type = BuildDceAclEntry_Type(ep->acltype,ep->name);
  1120.     
  1121.     if (strlen(ep->name) != 0)
  1122.        {
  1123.        id = BuildDceAclEntry_Id(rgy_site, ep->name, type);
  1124.        }
  1125.     
  1126.     status = 0;
  1127.     for (i = 0; i < new_sec_acls[0]->num_entries; i++)
  1128.        {
  1129.        if (new_sec_acls[0]->sec_acl_entries[i].entry_info.entry_type == type &&
  1130.        ((strlen(ep->name) != 0 && bcmp(new_sec_acls[0]->sec_acl_entries[i].entry_info.tagged_union.id.uuid, id, sizeof(uuid_t)) == 0) || strlen(ep->name) == 0))
  1131.       {
  1132.       status = 1;
  1133.       if (strcmp(ep->mode, "default") == 0)
  1134.          {
  1135.          new_sec_acls[0]->num_entries--;
  1136.          new_sec_acls[0]->sec_acl_entries[i] = new_sec_acls[0]->sec_acl_entries[new_sec_acls[0]->num_entries];
  1137.          }
  1138.       else
  1139.          {
  1140.          new_sec_acls[0]->sec_acl_entries[i].perms = BuildDceAclEntry_Perms(ep->mode, new_sec_acls[0]->sec_acl_entries[i].perms);
  1141.          }
  1142.       }
  1143.        }
  1144.     if (status == 0 && strcmp(ep->mode, "default") != 0)
  1145.        {
  1146.        if (strlen(ep->name) != 0)
  1147.       {
  1148.       new_sec_acls[0]->sec_acl_entries[new_sec_acls[0]->num_entries].entry_info.tagged_union.id.uuid = id;
  1149.       }
  1150.        new_sec_acls[0]->sec_acl_entries[new_sec_acls[0]->num_entries].entry_info.entry_type = type;
  1151.        new_sec_acls[0]->sec_acl_entries[new_sec_acls[0]->num_entries++].perms = BuildDceAclEntry_Perms(ep->mode, 0);
  1152.        }
  1153.     }
  1154.  
  1155.  status = 0;
  1156.  sec_rgy_site_close (rgy_site, &status);
  1157.  if (status != error_status_ok)
  1158.     {
  1159.     printf ("error: sec_rgy_site_close: %ld\n", status);
  1160.     }
  1161.  
  1162.  if (acl_list.sec_acls[0]->num_entries != new_sec_acls[0]->num_entries)
  1163.     {
  1164.     update = 1;
  1165.     }
  1166.  else
  1167.     {
  1168.     for (i = 0; i < acl_list.sec_acls[0]->num_entries; i++)
  1169.        {
  1170.        status = 0;
  1171.        for (j = 0; j < new_sec_acls[0]->num_entries; j++)
  1172.       {
  1173.       if (new_sec_acls[0]->sec_acl_entries[j].perms == acl_list.sec_acls[0]->sec_acl_entries[i].perms &&
  1174.           new_sec_acls[0]->sec_acl_entries[j].entry_info.entry_type == acl_list.sec_acls[0]->sec_acl_entries[i].entry_info.entry_type &&
  1175.           bcmp(new_sec_acls[0]->sec_acl_entries[j].entry_info.tagged_union.id.uuid,acl_list.sec_acls[0]->sec_acl_entries[i].entry_info.tagged_union.id.uuid, sizeof(uuid_t)) == 0)
  1176.          {
  1177.          status = 1;
  1178.          }
  1179.       }
  1180.        if (status == 0)
  1181.       {
  1182.       update = 1;
  1183.       }
  1184.        }
  1185.     }
  1186.  
  1187.  status = 0;
  1188.  
  1189.  if (update == 0)
  1190.     {
  1191.     Verbose("%s: No update necessary\n",VPREFIX);
  1192.     return false;
  1193.     }
  1194.  else
  1195.     {
  1196.     if (action == warnall || action == warnplain || action == warndirs)
  1197.        {
  1198.        sprintf(OUTPUT,"File %s needs ACL update\n",filename);
  1199.        CfLog(cfinform,OUTPUT,"");
  1200.        return false;
  1201.        }
  1202.     acl_list.sec_acls[0] = new_sec_acls[0];
  1203.     sec_acl_replace (h, manager_types, sec_acl_type_object, &acl_list, &status);
  1204.     if (status != error_status_ok)
  1205.        {
  1206.        printf ("error: sec_acl_replace: %ld\n", status);
  1207.        return false;
  1208.        }
  1209.     else
  1210.        {
  1211.        sprintf(OUTPUT,"ACL for file %s updated\n",filename);
  1212.        CfLog(cfinform,OUTPUT,"");
  1213.        return true;
  1214.        }
  1215.     }
  1216.  return true;
  1217. #endif
  1218. }
  1219.